/*
* O(n * sqrt(n))
* very long
*/

#pragma comment(linker, "/STACK:10000000")
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <set>
#include <map>
#include <cstdio>
#include <cassert>
#include <string>
#include <cstring>
#define ldb long double
#define LL long long
#define fi first
#define se second
#define fill(a, c) memset(a, c, sizeof(a))
#define sqr(a) ((a) * (a))
#define nextLine() {int c = 0; while((c = getchar()) != 10 && c != EOF);}
#define getBit(mask, k) (((mask) / pw[k]) % pw[1])
#define setBit(mask, k, l) (((mask) / pw[k + 1] * pw[1] + (l)) * pw[k] + ((mask) % pw[k]))
#define debug(a) cerr << #a << " = " << a << " ";
#define debugl(a) cerr << #a << " = " << a << "\n";

#ifndef JUGHEAD_TWOSTACKS_INCLUDED
#define JUGHEAD_TWOSTACKS_INCLUDED
#include <cstdlib>
#include <string>
using namespace std;

class TwoStacks
{
	public:
		int *fst, *sec, *fstmin, *secmin;
		int INF;
		int len1, len2;
		int size;
		TwoStacks();
		void init(int size);
		void push(const int &element);
		void update();
		void destroy();
		void pop();
		int getMinimum();
};
TwoStacks  :: TwoStacks()
{
	fst = sec = fstmin = secmin = NULL;
	len1 = len2 = size = 0;
}
void TwoStacks  :: destroy()
{
	if (fst)
		delete fst;
	if (sec)
		delete sec;
	if (fstmin)
		delete fstmin;
	if (secmin)
		delete secmin;
	fst = sec = fstmin = secmin = NULL;
	len1 = len2 = size = 0;
}

void TwoStacks  :: init(int sz)
{
	destroy();
	size = sz;
//	fst.resize(sz + 1);
//	sec.resize(sz + 1);
//	fstmin.resize(sz + 1);
//	secmin.resize(sz + 1);
	fst = new int[sz + 1];
	sec = new int[sz + 1];
	fstmin = new int[sz + 1];
	secmin = new int[sz + 1];
	len1 = 0;
	len2 = 0;
}

inline void TwoStacks  :: update()
{
	if (len2 < size) return;
	int mn = sec[len2 - 1];
	int x = 0;
	for (int i = len2 - 1; i >= 0; i--)
	{
		sec[i] += x;
		mn = min(mn, sec[i]);
		fst[len1] = sec[i];
		fstmin[len1++] = mn;
		x++;
	}
	len2 = 0;
}

inline void TwoStacks  :: push(const int &e)
{
	update();
	sec[len2] = e;
	secmin[len2] = e;
	if (len2 > 0) secmin[len2] = min(secmin[len2 - 1] + 1, e);
	len2++;
	if (len1 + len2 > size) pop();
}

inline void TwoStacks  :: pop()
{
	len1 = 0;
	update();
}

inline int TwoStacks  :: getMinimum()
{
	update();
	if (len1 + len2 > size) pop();
	if (len1 && len2)
		return min(fstmin[len1 - 1] + size - len1, secmin[len2 - 1]);
	else if (len1)
		return fstmin[len1 - 1];
	else if (len2)
		return secmin[len2 - 1];
	else return INF;
}

#endif



const ldb LDINF = 9128739847123.00;
const ldb eps = 1e-9;
const int INF = 1 << 28;
const ldb pi = fabsl(atan2(0.0, -1.0));
using namespace std;

const int MAXE = 2000010;
const int MAXV = 100010;
int first[MAXV], next[MAXE], end[MAXE];
int was[MAXV];
int cnt = 0;
int edges, n, m;
vector <int> a;

void addEdge(int a, int b)
{
	next[edges] = first[a];
	first[a] = edges;
	end[edges] = b;
	edges++;
}

void Load()
{
	cin >> n >> m;
	int i;
	memset(first, -1, sizeof first);
	int a, b;
	for (i = 0; i < m; i++)
	{
		scanf("%d%d", &a, &b);
		addEdge(a ,b);
		addEdge(b, a);
	}
}

int color = 0;
void dfs(int ver)
{
	was[ver] = color;
	cnt++;
	for (int u = first[ver]; u != -1; u = next[u])
	{
		if (was[end[u]] == 0)
			dfs(end[u]);
	}
}

bool good(int n)
{
	while (n)
	{
		if (n % 10 != 4 && n % 10 != 7) return false;
		n /= 10;
	}
	return true;
}

vector <pair <int, int> > all;
int res[100010];
int r2[100010];
TwoStacks st;



void Solve()
{
	for (int i = 1; i <= n; i++)
	{
		if (was[i] == 0)
		{
			color++;
			cnt = 0;
			dfs(i);
			a.push_back(cnt);
		}
	}
	sort(a.begin(), a.end());
	int mx = 0;
	for (int i = 0; i < a.size(); i++)
	{
		if (i == 0 || a[i] != a[i - 1])
		{
			all.push_back(make_pair(a[i], 0));
		}
		all[all.size() - 1].second++;
		mx = max(mx, all[all.size() - 1].second);
	}
	// knapsack O(sqrt(n) * n);
	for (int i = 0; i <= n; i++) res[i] = INF;
	res[0] = 0;
	st.init(n);
	st.INF = INF;
	for (int i = 0; i < all.size(); i++)
	{
		st.size = all[i].second;
		for (int j = 0; j < all[i].first; j++)
		{
			st.len1 = st.len2 = 0;
			for (int k = j; k <= n; k += all[i].first)
			{
				r2[k] = min(res[k], st.getMinimum() + 1);
				st.push(res[k]);
			}
		}
		for (int j = 1; j <= n; j++) res[j] = r2[j];
	}
	int result = INF;
	for (int i = 1; i <= n; i++)
		if (good(i))
			result = min(result, res[i]);

	if (result == INF)
	{
		cout << -1;
		return;
	}
	cout << result - 1;
}

#define file "e"
int main()
{
	#ifndef ONLINE_JUDGE
		freopen(file".in", "rt", stdin);
		freopen(file".out", "wt", stdout);
	#endif
	Load();
	Solve();
	return 0;
}
